home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
program
/
n_b_v203.zip
/
STR-MATH.UNT
< prev
next >
Wrap
Text File
|
1996-07-04
|
25KB
|
436 lines
$if 0
┌──────────────────────────╖ PowerBASIC v3.20
┌──┤ DASoft ╟──────────────────────┬──────────────────╖
│ ├──────────────────────────╢ Copyright 1995 │ DATE: 1996-01-01 ╟─╖
│ │ FILE NAME STR-MATH.UNT ║ by ╘════════════════─ ║ ║
│ │ LIBRARY DAS-NB03.PBL ║ Don Schullian, Jr. ║ ║
│ ╘══════════════════════════╝ ║ ║
│ A license is hereby granted to the holder to use this source code in ║ ║
│ any program, commercial or otherwise, without receiving the express ║ ║
│ permission of the copyright holder and without paying any royalties, ║ ║
│ as long as this code is not distributed in any compilable format. ║ ║
│ IE: source code files, PowerBASIC Unit files, and printed listings ║ ║
╘═╤═════════════════════════════════════════════════════════════════════╝ ║
│ ..................................... ║
╘═══════════════════════════════════════════════════════════════════════╝
$endif
'.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°
' ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° °
$if 1
$CODE SEG "DAS_NB03"
$EVENT OFF
$ERROR ALL OFF
$OPTIMIZE SPEED
$OPTION GOSUB OFF
$OPTION CNTLBREAK OFF
$OPTION SIGNED OFF
$DEBUG MAP OFF
$DEBUG PATH OFF
$DEBUG UNIT OFF
$COMPILE UNIT
$endif
'.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°
' ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° °
' PURPOSE: provide extended arithmetic functions for strings
' PARAMS: N1$ N1$ + N2$ or N1$ - N2$ or N1$ * N2$ or N1$ / N2$
' N2$ incoming numbers may be signed or not and pbvUsingChrs
' is used to determine which (if any) decimal point is used
' Decs% for DIVIDE only - the number of places past the decimal
' that are to be used in the answer
' RETURNS: the answer
' all values other than ZERO are signed with either + or -
' if the return value is ZERO then only a single "0" is returned
' NOTE: division by ZERO returns ZERO and not an error
' NOTE: N1$ * ".5" is faster than N1$ / "2"
'.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°.°
' ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° ° °
%F = 0 ' first pointer
%L = 1 ' last
%W = 2 ' working
%Pos = 43 ' plus sign
%Neg = 45 ' minus sign
DIM sN(2) AS SHARED STRING ' working strings
DIM sD(2,2) AS SHARED INTEGER ' sD%(0,X%) = places before decimal
' sD%(1,X%) = places past the decimal
' sD%(2,X%) = sign
DIM N_ptr(2,2) AS SHARED BYTE PTR ' N_ptr(%F,X%) = first digit
' N_ptr(%L,X%) = last digit
' N_ptr(%W,X%) = working digit
SHARED sD$, sA$, sZ$, sP$ ' dec$, ascii$, chr$(0), "."
' ──────────────────────────────────────────────────────────────────────────
FUNCTION fDIVnbr$( SEG N1$, SEG N2$, BYVAL Decs% ) LOCAL PUBLIC
LOCAL C%, L%, P%, X%
Format_NBRs N1$, N2$, ( 4 + Decs% ) ' get everybody ready
IF N_ptr(%F,0) = 0 THEN ' N1=0 or N2=0
FUNCTION = "0" ' function = 0
EXIT FUNCTION ' RETURN
END IF '
'
L% = LEN( sN$(2) ) ' length of divisor
IF sN$(1) < sN$(2) THEN INCR N_ptr(%F,0) ' if number > divisor
'
WHILE N_ptr(%F,0) =< N_ptr(%L,0) ' while still calculating
P% = L% ' P% = # of digits to use
IF sN$(1) < sN$(2) THEN INCR P% ' number is > divisor
IF @N_ptr(%F,0) = 46 THEN INCR N_ptr(%F,0) ' skip the decimal point
WHILE ( sN$(1) => sN$(2) ) OR ( P% > L% ) ' while N° > divisor
N_ptr(%W,1) = N_ptr(%F,1) + P% ' working pointers
N_ptr(%W,2) = N_ptr(%L,2) + 1 '
FOR X% = L% TO 1 STEP -1 ' do subtraction
DECR N_ptr(%W,1) ' decr pointers
DECR N_ptr(%W,2) '
IF ( C% > 0 ) THEN ' if carrying
IF @N_ptr(%W,1) > 0 THEN ' if digit > 0
DECR @N_ptr(%W,1) ' subtract carry amt
C% = 0 ' clear carry
ELSE ' else
@N_ptr(%W,1) = 9 ' carring a 9
END IF '
END IF '
IF @N_ptr(%W,2) > @N_ptr(%W,1) THEN ' if digit 1 > digit 2
C% = 10 ' carry 10
INCR @N_ptr(%W,1), C% ' bump digit 1
END IF '
DECR @N_ptr(%W,1), @N_ptr(%W,2) ' subtract d2 from d1
NEXT ' NEXT digit left
IF C% > 0 THEN ' if still carrying
DECR N_ptr(%W,1) ' prev digit
DECR @N_ptr(%W,1) ' decr ditit
C% = 0 ' clear carry
END IF '
IF (P% > L%) AND (ASCII( sN$(1) ) = 0) THEN ' check if right digit
P% = L% ' needs to fall off
MID$(sN$(1),1) = MID$( sN$(1),2) + sZ$ ' shift left
END IF '
INCR @N_ptr(%F,0) ' next digit in answer
WEND '
'
N_ptr(%W,1) = N_ptr(%L,1) ' check to see if number
FOR X% = LEN( sN$(1) ) TO 1 STEP -1 ' is now all ZERO's or
IF @N_ptr(%W,1) > 0 THEN EXIT FOR ' not
DECR N_ptr(%W,1) '
NEXT '
IF X% = 0 THEN EXIT LOOP ' Nope! - all done!
'
WHILE ASCII( sN$(1) ) = 0 ' if leading char ZERO
MID$( sN$(1), 1 ) = MID$(sN$(1),2) + sZ$ ' shift left
IF sN$(1) < sN$(2) THEN ' if number < divisor
INCR N_ptr(%F,0) ' skip digit in answer
IF @N_ptr(%F,0)=46 THEN INCR N_ptr(%F,0) ' skip decimal point
END IF '
WEND '
INCR N_ptr(%F,0) ' next digit in answer
WEND '
'
@N_ptr(%L,0) = 0 '
'
FUNCTION = fFormat_NBR$ ' clean-up & bail out!
END FUNCTION
' ──────────────────────────────────────────────────────────────────────────
FUNCTION fMULnbr$( SEG N1$, SEG N2$ ) LOCAL PUBLIC
LOCAL C%, D%, N1%, N2%, X%, Y%
Format_NBRs N1$, N2$, 3 ' get everybody ready
IF N_ptr(%F,0) = 0 THEN ' N1=0 or N2=0
FUNCTION = "0" ' function = 0
EXIT FUNCTION ' RETURN
END IF '
N1% = LEN( sN$